class Http {
  static instance: Http;
  config: HTTP.RequestConfig;

  constructor(config?: HTTP.RequestConfig) {
    this.config = {
      method: "POST",
      data: {},
      dataType: "json",
      timeout: 30000,
      headers: {
        "content-type": "application/x-www-form-urlencoded"
      },
      ...config
    };
  }

  get(options?: HTTP.RequestConfig) {
    return this.getHandle(options);
  }

  post(options?: HTTP.RequestConfig) {
    return this.postHandle(options);
  }

  /**
   *
   * @param options
   * @return {{code: number, message: string}|Promise<unknown>}
   * @private
   */
  private getHandle(options: HTTP.RequestConfig) {
    options.method = "GET";
    options.headers = this.mergeHeader(options.headers as HTTP.Headers);
    return this.request(options)
      .then(res => {
        return res;
      })
      .catch(err => {
        return Promise.reject(err);
      });
  }

  /**
   * post请求
   * @param options
   * @return {{code: number, message: string}|Promise<unknown>}
   * @private
   */
  private postHandle(options: HTTP.RequestConfig) {
    options.method = "POST";
    options.headers = this.mergeHeader(options.headers as HTTP.Headers);
    return this.request(options)
      .then(res => {
        return res;
      })
      .catch(err => {
        return Promise.reject(err);
      });
  }

  /**
   * 合并请求头
   * @param optHeader
   * @return {any}
   * @private
   */
  private mergeHeader(optHeader: HTTP.Headers) {
    const herder = JSON.parse(JSON.stringify(this.config.headers));
    if (!optHeader || typeof optHeader !== "object") {
      return herder;
    }
    Object.keys(herder).forEach(item => {
      if (optHeader[item]) {
        delete herder[item];
      }
    });
    return { ...herder, ...optHeader };
  }

  /**
   * 网络请求
   * @param config
   * @return {Promise<unknown>}
   * @private
   */
  private request(config) {
    const { url } = config;
    return new Promise((resolve, reject) => {
      if (!url) return reject(new Error("请求Url不能为空"));
      const _this = this;
      my.request({
        ...config,
        success(response) {
          // 可根据业务自定义
          const { status, data } = response;
          if (_this.isStatusSuccess(status)) {
            const { result } = data as any;
            resolve(result);
          } else {
            reject(response);
          }
        },
        fail(response) {
          reject(response);
        }
      });
    });
  }

  /**
   * 判断状态是否正常
   * @param {number} status
   * @returns {boolean} 状态是否正常
   */
  isStatusSuccess(status) {
    if (status >= 200 && status < 300) {
      return true;
    }
    return false;
  }

  /**
   * 在请求头注入Token
   * @param token
   */
  setHeaderToken(token: string): void {
    if (!token) {
      (this.config.headers as HTTP.Headers).token = token;
    }
  }

  static getInstance(): Http {
    if (!this.instance) {
      this.instance = new Http();
    }
    return this.instance;
  }
}

export default Http.getInstance();

export { Http };
